package demo.hdz.mediacodecdecode.filter;

import android.content.Context;
import android.content.res.AssetManager;
import android.opengl.GLES20;

import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

/**
 * @author hdz
 * @date 2022/05/28 16:48
 */
public abstract class BaseFilter {

    public String vShader;
    public String fShader;

    public BaseFilter() {

    }

    public BaseFilter(Context context, String vPath, String fPath) {
        AssetManager assetManager = context.getAssets();
        byte[] buf = new byte[2048*2];
        try {
            InputStream is = assetManager.open(vPath);
            is.read(buf, 0, 2048*2);
            vShader = new String(buf);
            is.close();

            InputStream is2 = assetManager.open(fPath);
            is2.read(buf, 0, 2048*2);
            fShader = new String(buf);
            is2.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public abstract void init();

    public abstract void release();

    public abstract void drawFrame(int textureId, float[] transformMatrix);

    public FloatBuffer createBuffer(float[] vertexData) {
        FloatBuffer buffer = ByteBuffer.allocateDirect(vertexData.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        buffer.put(vertexData, 0, vertexData.length).position(0);

        return buffer;
    }

    public ShortBuffer createBuffer(short[] vertexData) {
        ShortBuffer buffer = ByteBuffer.allocateDirect(vertexData.length * 2)
                .order(ByteOrder.nativeOrder())
                .asShortBuffer();
        buffer.put(vertexData, 0, vertexData.length).position(0);

        return buffer;
    }

    public IntBuffer createBuffer(int[] vertexData) {
        IntBuffer buffer = ByteBuffer.allocateDirect(vertexData.length * 4)
                .order(ByteOrder.nativeOrder())
                .asIntBuffer();
        buffer.put(vertexData, 0, vertexData.length).position(0);

        return buffer;
    }

    public int loadShader(int type, String shaderSource) {
        int shader = GLES20.glCreateShader(type);
        if (shader == 0) {
            throw new RuntimeException("Create Shader Failed!" + GLES20.glGetError());
        }
        GLES20.glShaderSource(shader, shaderSource);
        GLES20.glCompileShader(shader);

        return shader;
    }

    public int linkProgram(int verShader, int fragShader) {
        int program = GLES20.glCreateProgram();
        if (program == 0) {
            throw new RuntimeException("Create Program Failed!" + GLES20.glGetError());
        }
        GLES20.glAttachShader(program, verShader);
        GLES20.glAttachShader(program, fragShader);
        GLES20.glLinkProgram(program);

        GLES20.glUseProgram(program);

        return program;
    }

    public void setParameter(String key, int value) {

    }
}
